#!/usr/bin/env node
/* eslint-disable no-console */
import { Buffer } from 'node:buffer'
import process from 'node:process'

// 消息协议常量
const PROTOCOL_HEADER_SIZE = 4
const HEARTBEAT_INTERVAL = 3000

/**
 * 发送 Native Messaging 协议格式的消息给扩展程序
 *  @param {object} msg - 要发送的JSON消息
 * @returns {void} 无返回值
 */
function sendMessage(msg) {
  try {
    const payload = JSON.stringify(msg)
    const header = Buffer.alloc(PROTOCOL_HEADER_SIZE)
    header.writeUInt32LE(Buffer.byteLength(payload), 0)
    process.stdout.write(Buffer.concat([header, Buffer.from(payload)]))
  }
  catch (e) {
    console.error('[host] 消息序列化失败:', e)
  }
}

// 启动心跳检测
let lastHeartbeat = Date.now()
const heartbeatTimer = setInterval(() => {
  if (Date.now() - lastHeartbeat > HEARTBEAT_INTERVAL * 2) {
    console.error('[host] 心跳超时，退出进程')
    process.exit(1)
  }
}, HEARTBEAT_INTERVAL)

// 清除心跳定时器
// eslint-disable-next-line unused-imports/no-unused-vars, no-unused-vars
function stopHeartbeat() {
  clearInterval(heartbeatTimer)
}

console.log('[host] 服务已启动，等待扩展连接...')

// 消息缓冲区处理
let messageBuffer = Buffer.alloc(0)
process.stdin.on('readable', () => {
  let chunk
  // eslint-disable-next-line no-cond-assign
  while ((chunk = process.stdin.read()) !== null) {
    messageBuffer = Buffer.concat([messageBuffer, chunk])

    while (messageBuffer.length >= PROTOCOL_HEADER_SIZE) {
      const messageLength = messageBuffer.readUInt32LE(0)
      if (messageBuffer.length < PROTOCOL_HEADER_SIZE + messageLength) {
        break
      }

      try {
        const rawMessage = messageBuffer.slice(PROTOCOL_HEADER_SIZE, PROTOCOL_HEADER_SIZE + messageLength)
        const message = JSON.parse(rawMessage.toString())

        console.log(`[host] 收到消息: ${rawMessage.toString()}`)

        // 处理心跳包
        if (message.type === 'PING') {
          lastHeartbeat = Date.now()
          sendMessage({ type: 'PONG', timestamp: message.timestamp })
          console.debug('[host] 心跳响应已发送')
        }
        // 处理刷新请求 1
        else if (message.type === 'RELOAD_CSDN') {
          console.log('[host] 触发 csdn 页面刷新')
          sendMessage({
            type: 'RELOAD_CONFIRM',
            success: true,
            url: message.url,
          })
        }
      }
      catch (e) {
        console.error('[host] 消息解析失败:', e)
      }
      finally {
        messageBuffer = messageBuffer.slice(PROTOCOL_HEADER_SIZE + messageLength)
      }
    }
  }
})

// 异常处理
process.on('uncaughtException', (err) => {
  console.error('[host] 未捕获异常:', err)
  process.exit(1)
})
